<template>
    <div class="flex-box margin-right">
        <div class="flex-header">
            <el-input v-model="keyword" placeholder="请输入内容" clearable
                      style="width: 240px;">
                <template #append>
                    <el-button>
                        <i class="fa fa-search"></i>
                    </el-button>
                </template>
            </el-input>
            <el-button class="pull-right sea-btn-icon" @click="reload" :loading="loading">
                <i class="fa fa-refresh"></i>
            </el-button>
        </div>

        <div class="flex-body">
            <el-skeleton :data="tree" :loading="loading">
                <div class="margin-small hover-bg" style="display: inline-flex; justify-content: center;">
                    <span>当前选中：{{ selectGroup || '--' }}</span>
                    <a style="display: inline-flex; justify-content: center;line-height: 30px;" v-show="selectGroup"
                       @click="clean">
                        <icon-close></icon-close>
                    </a>
                </div>
                <el-tree ref="treeRef" :data="tree" :filter-node-method="filterNode"
                         default-expand-all :expand-on-click-node="false" @nodeClick="onNodeClick">
                    <template #default="{ node, data }">
                        <span :class="data.checked? 'text-primary': 'text-black'">{{ data.label }}</span>
                    </template>
                </el-tree>
            </el-skeleton>
        </div>
    </div>
    <!-- /.box -->
</template>


<script setup lang="ts">
// import create from "./create";
import {onMounted, ref, watch} from "vue";
import Bamboo, {TreeMapper, TreeNode} from "@/lang/bamboo";
import setting from "@/widget/provider/setting.js";
import Layers from "@/lang/layers/index";


/**
 * 带检索功能的树结构组件
 */
interface Props {
    // 请求 URL
    url: string;
    // 请求方法
    method?: Function;
    // 请求头配置
    headers?: Record<string, string>;
    /** 异步查询参数 */
    where?: Record<string, any>
    // 是否自动加载数据
    autoLoad?: boolean;
    // 数据查询执行器函数
    provider?: (config: any) => Promise<any>;

    // 数据映射配置
    mapper?: TreeMapper;


    /** model-value */
    modelValue?: number | string
    // 选项切换事件
    change?: (node: TreeNode) => void;
}

// 使用 withDefaults 设置默认值
const props = withDefaults(defineProps<Props>(), {
    method: 'GET',
    autoLoad: true,
    headers: {},
    provider: setting.ajax,
    mapper: () => Bamboo.mapper_default,
    change: Layers.method
})


// Emits
const emit = defineEmits(['update:modelValue']);

// 是否正在加载
const loading = ref(false);
// 树形数据
const tree = ref([]);

// 模糊搜索关键字
const keyword = ref('');

// 树对象实体
const treeRef = ref();

// 当前选中的节点
const selectGroup = ref('');

watch(keyword, val => {
    treeRef.value.filter(val)
});

/**
 * 模糊检索部门
 */
const filterNode = (value, data) => {
    if (!value) return true;
    return data.label.indexOf(value) !== -1;
}

// 点击高亮
const empty = {}
let preNode = empty;
const onNodeClick = (data) => {
    if (data !== preNode) {
        selectGroup.value = data.label;
        data.checked = true;
        preNode.checked = false;
        preNode = data;

        emit('update:modelValue', data.id);
        props.change(data);
    }
}

// 清除选中
const clean = () => {
    onNodeClick(empty);
}

const reload = () => {
    if (!loading.value) {
        props.provider({
            url: '/sys/dept/list',
            method: 'GET',
            params: props.params,
            header: props.headers
        }).then(list => {
            tree.value = Bamboo.toTree(list, props.mapper);
        }).finally(() => {
            loading.value = false;
        });
    }
}

onMounted(() => {
    if (props.autoLoad === true) {
        reload();
    }
})

</script>

<style scoped>

</style>